package cn.zcy.factory;

import cn.zcy.service.AccountService;
import cn.zcy.until.TransactionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
 * 用于生产service代理对象工厂
 */
@Component
public class ProxyServiceFactory {
    //被代理对象
    @Autowired
    private AccountService accountService;

    @Autowired
    private TransactionManager transactionManager;

    @Bean("proxyAccountService")
    public AccountService getProxyAccountService(){
        //创建代理对象
        /**
         * 参数1. 类加载器，用于加载代理对象的字节码，和被代理对象使用相同的类加载器，固定写法,
         * 参数2.字节码数组，用于给代理对象提供方法，和被代理对象具有相同的方法，固定写法
         * 参数3.要增强的方法，此处是一个接口，我们需要提供他的实现类，通常写的是匿名内部类。增强的代码使用谁写。
         */
        AccountService proxyAccountService = (AccountService)Proxy.newProxyInstance(accountService.getClass().getClassLoader(), accountService.getClass().getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

                //1.定义返回值
                Object retValue=null;
                try {
                    //开启事务
                    transactionManager.begin();
                    System.out.println("开启事务");
                    //执行被代理对象的方法
                    retValue = method.invoke(accountService, args);
                    //提交事务
                    transactionManager.commit();
                    System.out.println("提交事务");
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                    //回滚事务
                    System.out.println("回滚了事务");
                    transactionManager.rollback();
                } finally {
                    //关闭资源
                    transactionManager.close();
                    System.out.println("关闭资源");
                }
                //返回
                return retValue;
            }
        });
        //返回
        return proxyAccountService;
    }

}
